From: Paul Eggert Date: Tue, 30 Apr 2024 08:20:12 +0000 (-0700) Subject: etags: fix #line parsing (\\", long lines) X-Git-Tag: archive/raspbian/1%30.1+1-3+rpi1^2~14^2~18^2~1725 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=7e2309c6fc67b8149cc4c75f8d7f5f93e60b86c7;p=emacs.git etags: fix #line parsing (\\", long lines) * lib-src/etags.c (readline): Don’t mishandle lines like ‘#line 1 "a//"’, which has an escaped backslash before ‘"’. Don’t mishandle lines so long that sscanf overflows %n. --- diff --git a/lib-src/etags.c b/lib-src/etags.c index c316b3c7649..57ffbce380c 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -7375,26 +7375,26 @@ readline (linebuffer *lbp, FILE *stream) /* Check whether this is a #line directive. */ if (result > 12 && strneq (lbp->buffer, "#line ", 6)) { - intmax_t lno; - int start = 0; + char *lno_start = lbp->buffer + 6; + char *lno_end; + intmax_t lno = strtoimax (lno_start, &lno_end, 10); + char *quoted_filename + = lno_start < lno_end ? skip_spaces (lno_end) : NULL; - if (sscanf (lbp->buffer, "#line %"SCNdMAX" \"%n", &lno, &start) >= 1 - && start > 0) /* double quote character found */ + if (quoted_filename && *quoted_filename == '"') { - char *endp = lbp->buffer + start; + char *endp = quoted_filename; + while (*++endp && *endp != '"') + endp += *endp == '\\' && endp[1]; - while ((endp = strchr (endp, '"')) != NULL - && endp[-1] == '\\') - endp++; - if (endp != NULL) + if (*endp) /* Ok, this is a real #line directive. Let's deal with it. */ { char *taggedabsname; /* absolute name of original file */ char *taggedfname; /* name of original file as given */ - char *name; /* temp var */ + char *name = quoted_filename + 1; discard_until_line_directive = false; /* found it */ - name = lbp->buffer + start; *endp = '\0'; canonicalize_filename (name); taggedabsname = absolute_filename (name, tagfiledir);